/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.agile.main;

import com.agile.gerber2gcode.Cords;
import com.agile.gerber2gcode.GerberGCode;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;

/**
 *
 * @author Rko
 */
public class Frame extends javax.swing.JFrame {

    Properties prop = new Properties();
    String inputFilename = "";
    String outputFilename = "";

    /**
     * Creates new form NewJFrame1
     */
    public Frame() {
        initComponents();
        getProperties();
        makeMenu();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        gerberFile = new javax.swing.JTextArea();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jTextField1 = new javax.swing.JTextField();
        load = new javax.swing.JButton();
        jTextField2 = new javax.swing.JTextField();
        jTextField3 = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jButton4 = new javax.swing.JButton();
        jButton5 = new javax.swing.JButton();
        jButton6 = new javax.swing.JButton();
        jButton7 = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        debug = new javax.swing.JTextArea();
        jLabel4 = new javax.swing.JLabel();
        jScrollPane3 = new javax.swing.JScrollPane();
        gCodeFile = new javax.swing.JTextArea();
        generate = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jLabel1.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N
        jLabel1.setText("Fichero : ");

        gerberFile.setColumns(20);
        gerberFile.setRows(5);
        jScrollPane1.setViewportView(gerberFile);

        jButton1.setFont(new java.awt.Font("Tahoma", 1, 48)); // NOI18N
        jButton1.setText("Iniciar");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jButton2.setFont(new java.awt.Font("Tahoma", 1, 48)); // NOI18N
        jButton2.setText("Detener");

        jTextField1.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N

        load.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N
        load.setText("...");
        load.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                loadActionPerformed(evt);
            }
        });

        jTextField2.setFont(new java.awt.Font("Tahoma", 1, 32)); // NOI18N

        jTextField3.setFont(new java.awt.Font("Tahoma", 1, 32)); // NOI18N

        jLabel2.setFont(new java.awt.Font("Tahoma", 1, 36)); // NOI18N
        jLabel2.setText("X :");
        jLabel2.setToolTipText("");

        jLabel3.setFont(new java.awt.Font("Tahoma", 1, 36)); // NOI18N
        jLabel3.setText("Y : ");

        jButton4.setFont(new java.awt.Font("Tahoma", 1, 24)); // NOI18N
        jButton4.setText("Y+");

        jButton5.setFont(new java.awt.Font("Tahoma", 1, 24)); // NOI18N
        jButton5.setText("Y-");

        jButton6.setFont(new java.awt.Font("Tahoma", 1, 24)); // NOI18N
        jButton6.setText("X+");

        jButton7.setFont(new java.awt.Font("Tahoma", 1, 24)); // NOI18N
        jButton7.setText("X-");

        debug.setColumns(20);
        debug.setRows(5);
        jScrollPane2.setViewportView(debug);

        jLabel4.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N
        jLabel4.setText("Alinear");

        gCodeFile.setColumns(20);
        gCodeFile.setRows(5);
        jScrollPane3.setViewportView(gCodeFile);

        generate.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
        generate.setText("Generar gCode");
        generate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                generateActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 269, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(load)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(generate))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 187, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 204, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jButton1)
                                .addGap(61, 61, 61)
                                .addComponent(jButton2))
                            .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jButton5)
                                    .addComponent(jButton4))
                                .addGap(201, 201, 201))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jButton7)
                                .addGap(116, 116, 116)
                                .addComponent(jButton6)
                                .addGap(112, 112, 112))
                            .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(layout.createSequentialGroup()
                                        .addGap(2, 2, 2)
                                        .addComponent(jLabel2))
                                    .addComponent(jLabel4)
                                    .addComponent(jLabel3))
                                .addGap(38, 38, 38)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                    .addComponent(jTextField2)
                                    .addComponent(jTextField3, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)))
                            .addComponent(jScrollPane2))))
                .addContainerGap(37, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(load)
                    .addComponent(generate))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jButton1)
                            .addComponent(jButton2))
                        .addGap(28, 28, 28)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jTextField2))
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel3))
                        .addGap(34, 34, 34)
                        .addComponent(jLabel4)
                        .addGap(17, 17, 17)
                        .addComponent(jButton4)
                        .addGap(22, 22, 22)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jButton6)
                            .addComponent(jButton7))
                        .addGap(22, 22, 22)
                        .addComponent(jButton5)
                        .addGap(8, 8, 8)
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 263, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                            .addComponent(jScrollPane3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 687, Short.MAX_VALUE)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING))
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_jButton1ActionPerformed

    private void loadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadActionPerformed
        String line;
        File file;

        JFileChooser dialog = new JFileChooser();

        if (dialog.showOpenDialog(gerberFile) == JFileChooser.APPROVE_OPTION) {
            file = dialog.getSelectedFile();

            String[] name = file.getName().split("\\.");

            debug.append("Fichero Gerber : \n");
            debug.append(name[0] + "\n");
            debug.append(file.getAbsolutePath() + "\n");
            debug.append("Carpeta : \n");
            debug.append(file.getParent() + "\n");

            outputFilename = file.getParent() + File.separator + name[0] + ".gcode";
            inputFilename = file.getAbsolutePath();

            try {
                BufferedReader input = new BufferedReader(new FileReader(file));
                gerberFile.setText("");
                line = input.readLine();
                while (line != null) {
                    gerberFile.append(line + "\n");
                    line = input.readLine();
                }
                input.close();
            } catch (IOException e) {
                JOptionPane.showMessageDialog(gerberFile, "No se puede cargar Fichero Gerber " + e.getMessage());
            }
            gerberFile.setCaretPosition(1);

        }// TODO add your handling code here:
    }//GEN-LAST:event_loadActionPerformed

    private void generateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_generateActionPerformed
        // TODO add your handling code here:
        GerberGCode gerberGcode;
        String[] splitline;
        boolean debug = false;

        BufferedReader in;
        String line;
        String formatX = "23", formatY = "23";
        boolean inInch = false;

        // Config
        float penWidth = 0.7f;
        float offsetX = 40;
        float offsetY = 40;
        int XYFeedrate = 1000;
        int ZFeedrate = 70;
        float drawingHeight = 1.8f;
        float freemoveHeight = 3.8f;//1.7f;
        // Config end

        this.debug.append("Gerber RS274X covertir a GCoder\n");

        this.debug.append("Fichero de entrada : " + inputFilename + "\n");
        this.debug.append("Fichero de salida: " + outputFilename + "\n");
        /*this.debug.append("Pen Width: " + penWidth + " mm" + "\n");
         this.debug.append("Offset X: " + offsetX + " mm" + "\n");
         this.debug.append("Offset Y: " + offsetY + " mm" + "\n");
         this.debug.append("Drawing Height: " + drawingHeight + " mm" + "\n");
         this.debug.append("Freemove Height: " + freemoveHeight + " mm\n");*/

        gerberGcode = new GerberGCode(penWidth, drawingHeight, freemoveHeight, XYFeedrate, ZFeedrate);
        // processing Gerber file
        try {
            in = new BufferedReader(new FileReader(inputFilename));

            while ((line = in.readLine()) != null) {
                if (debug) {
                    System.out.println(line);
                }

                if (line.startsWith("%FSLA")) {

                    formatX = line.substring(6, 8);
                    formatY = line.substring(9, 11);
                    if (debug) {
                        System.out.println("Format X: " + formatX + " Format Y: " + formatY);
                    }
                } else if (line.startsWith("%ADD")) {
                    String apertureNum, apertureType, apertureSize;

                    line = line.substring(4, line.length() - 2);
                    apertureNum = line.substring(0, 2);

                    line = line.substring(2);
                    splitline = line.split(",");
                    apertureType = splitline[0];
                    apertureSize = splitline[1];

                    if (debug) {
                        System.out.println("\n\nAparture: " + apertureNum);
                        System.out.println("Type: " + apertureType);
                        System.out.println("Size: " + apertureSize);
                    }

                    if (apertureType.equals("C")) {
                        gerberGcode.addCircleAperture(Integer.parseInt(apertureNum), Float.parseFloat(apertureSize));
                    } else if (apertureType.equals("R")) {

                        String rectSides[] = apertureSize.split("X");

                        gerberGcode.addRectangleAperture(Integer.parseInt(apertureNum), Float.parseFloat(rectSides[0]), Float.parseFloat(rectSides[1]));
                    } else if (apertureType.equals("OC8")) {
                        gerberGcode.addCircleAperture(Integer.parseInt(apertureNum), Float.parseFloat(apertureSize));
                    } else {
                        System.out.println(" [-] aparture type: " + apertureType + " not supported [" + line + "]\n");
                        //System.exit(-1);
                    }

                } else if (line.startsWith("G90")) {
                    gerberGcode.enableAbsolute();
                } else if (line.startsWith("G91")) {
                    gerberGcode.enableRelative();
                } else if (line.startsWith("G70")) {
                    gerberGcode.setImperial();
                    inInch = true;

                    offsetX = offsetX / 25.4f;
                    offsetY = offsetY / 25.4f;
                } else if (line.startsWith("G71")) {
                    gerberGcode.setMetric();
                } else if (line.startsWith("G54")) {
                    int aperture;

                    aperture = Integer.valueOf(line.substring(4, line.length() - 1).trim());
                    gerberGcode.selectAperture(aperture);

                } else if (line.startsWith("X")) {
                    float x, y;
                    int d;
                    int divFactorX = (int) Math.pow(10.0, Integer.parseInt(formatX.substring(1)));
                    int divFactorY = (int) Math.pow(10.0, Integer.parseInt(formatY.substring(1)));

                    x = Float.valueOf(line.substring(1, line.indexOf("Y"))) / divFactorX;
                    y = Float.valueOf(line.substring(line.indexOf("Y") + 1, line.indexOf("D"))) / divFactorY;
                    d = Integer.valueOf(line.substring(line.indexOf("D") + 1, line.indexOf("D") + 3));

                    x += offsetX;
                    y += offsetY;

                    if (debug) {
                        System.out.println(" X: " + x + " Y:" + y + " D:" + d);
                    }

                    if (d == 1) {
                        gerberGcode.addLine(new Cords(x, y, inInch));
                    } else if (d == 2) {
                        gerberGcode.goTo(new Cords(x, y, inInch));
                    } else if (d == 3) {
                        gerberGcode.exposePoint(new Cords(x, y, inInch));
                    }
                } else if (line.startsWith("D")) {
                    int aperture;

                    aperture = Integer.valueOf(line.substring(1, 3));
                    gerberGcode.selectAperture(aperture);
                }
            }

			//System.out.println(gerberGcode.getGCode());
            BufferedWriter outfile;

            outfile = new BufferedWriter(new FileWriter(outputFilename));
            outfile.write(gerberGcode.getGCode());
            outfile.close();

            System.out.println("GCode file generated succesfully !");

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //----------------------------------------------------------------------
        try {
            File fileout = new File(outputFilename);
                BufferedReader input = new BufferedReader(new FileReader(fileout));
                gCodeFile.setText("");
                line = input.readLine();
                while (line != null) {
                    gCodeFile.append(line + "\n");
                    line = input.readLine();
                }
                input.close();
            } catch (IOException e) {
                JOptionPane.showMessageDialog(gCodeFile, "No se puede cargar Fichero Gerber " + e.getMessage());
            }
            gCodeFile.setCaretPosition(1);
        
    }//GEN-LAST:event_generateActionPerformed

    private void getProperties() {
        String propFileName = "com/agile/resources/string.properties";
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream(propFileName);
        try {
            prop.load(inputStream);
            if (inputStream == null) {
                JOptionPane.showMessageDialog(this,
                        "Fichero string.properties no se encontro",
                        "Error",
                        JOptionPane.ERROR_MESSAGE);
            }
        } catch (IOException ex) {
            Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private void makeMenu() {
        JMenuBar menuBar = new JMenuBar();
        setJMenuBar(menuBar);
        JMenu fileMenu = new JMenu(prop.getProperty("menu_file"));

        menuBar.add(fileMenu); // Add the file menu

        JMenuItem elementoSalir = new JMenuItem("Salir");
        elementoSalir.setMnemonic('S');
        fileMenu.add(elementoSalir);
        elementoSalir.addActionListener(
                new ActionListener() {  // clase interna anónima

                    // terminar la aplicación cuando el usuario haga clic en elementoSalir
                    public void actionPerformed(ActionEvent evento) {
                        System.exit(0);
                    }

                } // fin de la clase interna anónima

        ); // fin de la llamada a addActionListener

    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextArea debug;
    private javax.swing.JTextArea gCodeFile;
    private javax.swing.JButton generate;
    private javax.swing.JTextArea gerberFile;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton4;
    private javax.swing.JButton jButton5;
    private javax.swing.JButton jButton6;
    private javax.swing.JButton jButton7;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JTextField jTextField2;
    private javax.swing.JTextField jTextField3;
    private javax.swing.JButton load;
    // End of variables declaration//GEN-END:variables
}
